package com.sinszm.sofa;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.ObjectUtil;
import com.sinszm.sofa.annotation.QJob;
import com.sinszm.sofa.exception.ApiException;
import com.sinszm.sofa.util.BaseUtil;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceInitializationMode;

import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

import static org.springframework.boot.jdbc.DataSourceInitializationMode.ALWAYS;

/**
 * 基础配置
 *
 * @author admin
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@ConfigurationProperties("quartz")
public class SzmQuartzProperties {

    /**
     * 指定数据源实例名称
     */
    private String dataSource;

    /**
     * 模式
     */
    private DataSourceInitializationMode mode;

    /**
     * 任务实例名
     */
    private String instanceName;

    /**
     * 基本包
     */
    private List<String> basePackages;

    /**
     * 基本包类
     */
    private List<Class<?>> basePackagesClasses;

    /**
     * 扫描任务是否启用，默认不启用初始化扫描任务
     */
    private boolean scanTask = false;

    /**
     * 检查所有
     *
     * @return {SzmQuartzProperties}
     */
    public SzmQuartzProperties checkAll() {
        Assert.notEmpty(BaseUtil.trim(this.dataSource), () -> new ApiException("202", "请先指定数据源实例名称"));
        this.dataSource = BaseUtil.trim(this.dataSource);
        this.mode = mode == null ? ALWAYS : this.mode;
        this.instanceName = BaseUtil.isEmpty(this.instanceName) ? "quartzScheduler" : this.instanceName;
        return this;
    }

    /**
     * 获取所有具备QJob注解的类
     *
     * @return 类加载
     */
    public SzmQuartzProperties jobClasses() {
        List<Class<?>> classes = new LinkedList<>();
        if (ObjectUtil.isNotEmpty(this.basePackages)) {
            for (String basePackage : basePackages) {
                classes.addAll(ClassUtil.scanPackageByAnnotation(basePackage, QJob.class));
            }
        }
        if (ObjectUtil.isNotEmpty(basePackagesClasses)) {
            classes.addAll(basePackagesClasses);
        }
        this.basePackagesClasses = classes.stream().distinct().collect(Collectors.toList());
        return this;
    }

}
